package com.cipe.cmrs.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Service;

import com.cipe.cmrs.bean.RestrictedUiElementBean;
import com.cipe.cmrs.bean.RestrictedUiElementRoleEntryBean;
import com.cipe.cmrs.dao.BaseRefDao;
import com.cipe.cmrs.dao.RestrictedUiElementDao;
import com.cipe.cmrs.model.RestrictedUiElements;
import com.cipe.cmrs.model.Role;
import com.cipe.cmrs.model.User;
import com.cipe.cmrs.service.RestrictedUiElementsService;
import com.cipe.cmrs.service.RoleService;
 
@Service
public class RestrictedUiElementsServiceImpl implements RestrictedUiElementsService {
    @Autowired
    private BaseRefDao dao;
    
    @Autowired
    private RestrictedUiElementDao ruieDao;

	@Autowired
	private RoleService			roleService;
	
	@Autowired
	private ConversionService conversionService;
	
	private List<String> elementAndRolePair = null;
	
	@SuppressWarnings("unchecked")
	public Map<String, List> getRoleManagementData() {
		Map<String, List> rmbData = new HashMap<String, List>();
		List<RestrictedUiElementRoleEntryBean> checkedRoleList = new ArrayList<RestrictedUiElementRoleEntryBean>();
		List<RestrictedUiElementBean> uiElementBeanList = new ArrayList<RestrictedUiElementBean>();
		List<Role> allRoles = roleService.findAll();

		List<com.cipe.cmrs.model.RestrictedUiElements> uiElelements = (List<com.cipe.cmrs.model.RestrictedUiElements>) ruieDao
				.findAll(com.cipe.cmrs.model.RestrictedUiElements.class);

		RestrictedUiElementBean bean = null;
		RestrictedUiElementRoleEntryBean rereb = null;

		for (com.cipe.cmrs.model.RestrictedUiElements restrictedUiElement : uiElelements) {
			bean = new RestrictedUiElementBean(restrictedUiElement.getId(), restrictedUiElement.getSubMenuOrForm(), restrictedUiElement.getNameOrValue());
			List<RestrictedUiElementRoleEntryBean> uiElementBeanRoleEntryList = bean.getRolesEntryList();

			Set<Role> linkRoles = restrictedUiElement.getRoles();
			for (Role role : allRoles) {
				if (linkRoles.contains(role)) {
					rereb = new RestrictedUiElementRoleEntryBean(restrictedUiElement.getId(), role.getId(), restrictedUiElement.getNameOrValue(), restrictedUiElement.getSubMenuOrForm(), Boolean.TRUE);
					checkedRoleList.add(rereb);
				} else {
					rereb = new RestrictedUiElementRoleEntryBean(restrictedUiElement.getId(), role.getId(), restrictedUiElement.getNameOrValue(), restrictedUiElement.getSubMenuOrForm(), Boolean.FALSE);
				}
				uiElementBeanRoleEntryList.add(rereb);
			}
			uiElementBeanList.add(bean);

		}
		rmbData.put("uiElementBeanList", uiElementBeanList);
		rmbData.put("checkedRoleList", checkedRoleList);
		return rmbData;
	}
	
	@SuppressWarnings("unchecked")
    public Map<String, Map<String, String>> getAllAllowedUiElements(User user) {
		List<RestrictedUiElements> tempList = ruieDao.getRestrictedUiElementsByUserRoles(user);
		
        Map<String, Map<String, String>> results = new HashMap<String, Map<String, String>>();
        if (tempList != null && tempList.size() > 0) {
            for (RestrictedUiElements el : tempList) {
                String subMenuOrForm = el.getSubMenuOrForm();
                if (StringUtils.isBlank(subMenuOrForm)) {
                    subMenuOrForm = "";
                }
                Map<String, String> map = results.get(subMenuOrForm);
                if (map == null) {
                    map = new HashMap<String, String>();
                    results.put(subMenuOrForm, map);
                }
                map.put(el.getNameOrValue(), el.getNameOrValue());
            }
        }
        return results;        
	}
	
	public void saveUiElementsRoles(Map<Integer, List<Integer>> uiElementsRoles){
		Set<Integer> uiElementIds = uiElementsRoles.keySet();
		for (Integer uiElementId : uiElementIds) {
	    	boolean hasChanges = false;
			
	    	com.cipe.cmrs.model.RestrictedUiElements dbUiElement = (com.cipe.cmrs.model.RestrictedUiElements)ruieDao.findById(com.cipe.cmrs.model.RestrictedUiElements.class, uiElementId);
	    	
			Set<Role> dbUiElementRoles = dbUiElement.getRoles();
			List<Integer> roleIds = uiElementsRoles.get(uiElementId);
			// util methode return two list one for add the second one for removing entities from table.
	        List<List<Role>> dataList = getUiElementAddOrRemoveRoleList(dbUiElementRoles, roleIds);

	        List<Role> uiElementAddRoleList = dataList.get(0); 
	    	List<Role> uiElementRemoveRoleList = dataList.get(1);

	    	if(uiElementRemoveRoleList.size() > 0){
	    		dbUiElementRoles.removeAll(uiElementRemoveRoleList);
	    		hasChanges = true;
	    	}	    	
	    	if(uiElementAddRoleList.size() > 0){
	    		dbUiElementRoles.addAll(uiElementAddRoleList);
	    		hasChanges = true;
	    	}
	    	// execute update only when any roles was added or removed.
	    	if(hasChanges){
	    		ruieDao.update(dbUiElement);
	    	}			
		}
	}
	
    @SuppressWarnings("unused")
	private List<List<Role>> getUiElementAddOrRemoveRoleList(Set<Role> dbUiElementRoles, List<Integer> roleIds){
    	List<Role> uiElementRoleAddList = new ArrayList<Role>(); 
    	List<Role> uiElementRoleRemoveList = new ArrayList<Role>();

    	// adding UiElement Role which must be remove.
    	for (Role dbUiElementRole : dbUiElementRoles) {
			if(!roleIds.contains(dbUiElementRole.getId())){
				uiElementRoleRemoveList.add(dbUiElementRole);
			}			
		}    	
    	// adding UiElement Role which must be add.
    	for (Integer roleId : roleIds) {
    		Role uiElementRole = roleService.findById(roleId);
			if(!dbUiElementRoles.contains(uiElementRole)){
				uiElementRoleAddList.add(uiElementRole);		
			}
		}
        
        List<List<Role>> addAndRemoveList = new ArrayList<List<Role>>();
        addAndRemoveList.add(uiElementRoleAddList);
        addAndRemoveList.add(uiElementRoleRemoveList);

    	return addAndRemoveList;
    }
}
